<?php

/**
 * lrn框架之核心文件
 * 本文件是lrn框架的基础文件，所有自定义app都要包含此文件，以便运行之
 * 
 * 本文件的思路参考过以下程序，在此一并致谢！
 * - ThinkPHP 2.0{@link http://www.thinkphp.cn}
 * - CMSTOP 2010 PUBLIC{@link http://www.cmstop.com/}
 * - xweibo{@link http://x.weibo.com}
 * - Comsenz UCenter{@link http://www.comsenz.com}
 * 
 * @author Horse Luke<horseluke@126.com>
 * @copyright Horse Luke, 2010
 * @license the Apache License, Version 2.0 (the "License"). {@link http://www.apache.org/licenses/LICENSE-2.0}
 * @version $Id: lrn.php 140 2010-11-20 14:48:08Z horseluke@126.com $
 * @package lrn_framework
 */
class lrn{
    
    //已经导入了的的文件
    protected static $_importFile = array();
    
    //系统设置
    protected static $_config = array();
    
    /**
     * 获取本框架的版本
     *
     * @return array
     */
    public static function version(){
        return array('main' => '0.1', 'release' => '20101023');
    }

    /**
     * 按照别名规则，导入指定文件。
     * 规则：和java类似，但此处仅允许导入单文件。在第二个参数$basePath为空的情况下，第一个点号前的规则如下：
     * - 如果命名为app，则表示导入定义了APP_PATH目录下面的文件。
     * - 比如app.controller.article表示导入APP_PATH/controller/article.php文件
     * 本方法曾参考：ThinkPHP 2.0, CMSTOP 2010 PUBLIC
     * 
     * @uses SYS_PATH | APP_PATH
     * @param string $alias 别名规则。分割可用.或者/
     * @param string $basePath 别名所在起始目录路径，结尾不要加/
     * @param string $ext 文件后缀名
     * @return boolen
     */
    public static function import( $alias, $basePath = '', $ext = '.php' ){
        $flag = $alias . $basePath . $ext;
        if (isset( self::$_importFile[$flag] )) {
            return true;
        }
        $classPath = str_replace( '.', '/', $alias );
        if (empty( $basePath )) {
            $structure = explode( '/', $classPath );
            if ('app' == $structure[0]) {
                $basePath = APP_PATH;
                $classPath = substr( $classPath, strlen( $structure[0] ) + 1 );
            } else {
                $basePath = SYS_PATH;
            }
        }
        //转换为绝对路径，同时检测文件是否存在
        $file = realpath( $basePath . DIRECTORY_SEPARATOR . $classPath . $ext );
        if (false == $file) {
            self::$_importFile[$flag] = false;
            return false;
        }
        self::$_importFile[$flag] = $file;
        require_once $file;
        return true;
    }

    
    /**
     * 自动导入遵循本框架命名规则的class文件函数（仿照Zend框架命名）。用法：
     * PHP5.0以上：该文件已经包含了函数__autoload，来引导php自动完成导入。
     * PHP5.1.2及以上：可以通过该文件已经包含了函数__autoload实现，或者使用SPL函数告知php应该如何自动导入（使用了SPL，函数__autoload将自动失效）：
     * spl_autoload_register(array('Inter','loadClass'));
     * 
     * @uses SYS_PATH
     * @param string $classname 遵循本框架命名规则的class名称
     */
    public static function importSys( $classname ){
        $classpath = str_replace( '_', '/', $classname );
        self::import( $classpath, SYS_PATH );
    }
    
    
    
    /**
     * 在一个数组中，依据一个path获取数组的内容
     * @param string $path 获取的数组索引路径。比如newset、newset/1等
     * @param array $arraySearch 要搜寻的数组
     * @param string $default 默认值。如果该索引变量无设置，那么就返回此值。默认为null
     */
    public static function arrayGet( $path, $arraySearch, $default = null ){
        $temp = $arraySearch;
        $path = explode( '/', trim( $path ) );
        foreach ($path as $k => $index) {
            if ( !is_array($temp) || !isset( $temp[$index] ) ) {
                $temp = $default;
                break;
            }
            $temp = $temp[$index];
        }
        return $temp;
    }
    
    
    /**
     * 设置或者返回参数名称
     * @param string $name 如果传入空值，则表示返回所有设置值。否则则返回单一的设置
     * @param mixed $value 设置值，如果传入，则表示设置$name为$value
     */
    public static function config($name=null, $value = null){
        
        if( empty($name) ){
            return self::$_config;
        }elseif( is_string($name) ){
            $name = strtoupper($name);
            
            if( is_null($value) ){
                return isset( self::$_config[$name] ) ? self::$_config[$name] : null;
            }else{
                self::$_config[$name] = $value;
                return true;
            }
            
        }elseif( is_array($name) ){
            self::$_config = array_merge( self::$_config, array_change_key_case($value, CASE_UPPER) );
            return true;
        }else{
            return null;
        }
        
    }
    
    /**
     * 启动框架
     */
    public static function boot(){
        $GLOBALS['_starttime'] = microtime();
        ini_set( 'magic_quotes_runtime', 0 );
        define ( 'IN_LRN_SYS', true );
        
        //定义核心框架目录常量
        if (! defined( 'SYS_PATH' )) {
            define( 'SYS_PATH', dirname( __FILE__ ) );
        }
        
        //定义app名称常量
        if (! defined( 'APP_NAME' )) {
            define( 'APP_NANE', basename( APP_PATH ) );
        }
        
        //导入配置文件
        lrn::config( require SYS_PATH. '/config/config.php' );
        $appconfig = APP_PATH. '/config/config.php';
        if( is_file($appconfig) ){
            lrn::config( require $appconfig );
        }
        
        // 设置系统时区(PHP5必须，否则在STRICT环境下报错)
        if(function_exists('date_default_timezone_set')){
            date_default_timezone_set( lrn::config('TIME_ZONE') );
        }
        
    }
    
    
    
}


/**
 * 自动导入框架文件
 * @param string $classname
 */
function __autoload( $classname ){
    lrn::importSys( $classname );
}